var maxSendDataLength = 120;
var sendDataWaitTime = 20;
var connectedDeviceId = "";
var connectedDevicServiceId = "";
var deviceInfoServiceId = "";
var writeCharacteristicsId = "";
var notifyCharacteristicsId = "";
var interval = null;
var printList = [];
var supportPrefixKeys = [];
var printHex = "";
var sDidSendDataHandler;
var sDidSendHexHandler;
var sDidConnectedHandler;
var currentPrinter = {
	"name": "",
	"DPI": 203,
	"width": 384
};
module.exports = {
	"setSupportPrefixs": setSupportPrefixs,
	"startScanPeripherals": startScanPeripherals,
	"stopScanPeripherals": stopScanPeripherals,
	"connectPeripheral": connectPeripheral,
	"disconnectPeripheral": disconnectPeripheral,
	"scanedPeripherals": scanedPeripherals,
	"sendData": sendData,
	"currentConnectedDeviceId": currentConnectedDeviceId,
	"currentPrinterInfo": currentPrinterInfo,
	"setCurrentPrinterInfoProperty": setCurrentPrinterInfoProperty
};




function currentPrinterInfo() {
	return currentPrinter;
}

function setCurrentPrinterInfoProperty(filed, value) {
	currentPrinter[filed] = value;
}

function setSupportPrefixs(prefixs) {
	supportPrefixKeys = prefixs;
}

/**
 * _0x120f29 res success closeBluetoothAdapter
 * _0xb1163d res success openBluetoothAdapter
 * _0xc362f3 res success startBluetoothDevicesDiscovery
 * 
 * @param {*} conDevPrinter 
 */
function startScanPeripherals(conDevPrinter) {
	wx.closeBluetoothAdapter({
		success(res) {
			console.log("【ble1】closeBluetoothAdapter--->", res)
			wx.openBluetoothAdapter({
				success(res) {
					console.log("【ble2】openBluetoothAdapter--->", res)
					wx.startBluetoothDevicesDiscovery({
						success(res) {
							// TOLOOK
							console.log("【ble3】startBluetoothDevicesDiscovery--->", res)

							wx.onBluetoothDeviceFound((res) => {
								var devList = new Array();
								for (var i = 0; i < res.devices.length; i++) {
									let devName = res.devices[i].name;
									if (isMyPrinterForName(devName)) {
										console.log("---printerName>", devName)
										devList.push(res.devices[i]);
									}
								}
								if(devList.length > 0 && conDevPrinter) {
									conDevPrinter(devList);
								}
							})
							// setTimeout(function () {
							// 	scanedPeripherals(function (devList) {
							// 		console.log("scanedPeripherals--->", devList)
                                    
							// 		if (conDevPrinter) {
							// 			conDevPrinter(devList);
							// 		}
							// 	});
							// }, 2000);
						}
					});
					wx.onBluetoothAdapterStateChange(function (res) {
						console.log("【ble】onBluetoothAdapterStateChange--->", res)
					});
				}
			});
		}
	});
}




function currentConnectedDeviceId() {
	return connectedDeviceId ? connectedDeviceId : "";
}




function stopScanPeripherals() {
	wx.stopBluetoothDevicesDiscovery({
		success: function (res) {}
	});
}

function connectPeripheral(devId, didConnectedHandler, setCurrentPrinterInfo) {
	sDidConnectedHandler = didConnectedHandler;
	wx.onBLEConnectionStateChange(function (res) {
		if (res.deviceId != connectedDeviceId) {
			return;
		}

		if (!res.connected) {
			if (setCurrentPrinterInfo) {
				setCurrentPrinterInfo();
			}
		}
	});
	wx.onBLECharacteristicValueChange(function (res) {
		if (res.deviceId != connectedDeviceId) {
			return;
		}

		if (res.characteristicId.indexOf("00002A24") == 0) {
			parseDeviceInfo(res);
		} else if (res.characteristicId == notifyCharacteristicsId) {
			//特征最新的值  
			var characterVal = new Uint8Array(res.value);

			if (characterVal.length > 2 && characterVal[0] == 31) {
				if (characterVal[1] == 113) {
					parseDPI(characterVal);
				} else if (characterVal[1] == 114) {
					parsePrintWidth(characterVal);
				} else if (characterVal[1] == 119) {
					parseBufferSize(characterVal);
				}
			}
		}
	});
	stopScanPeripherals();
	wx.createBLEConnection({
		deviceId: devId,
		success: function (res) {
			connectedDeviceId = devId;
			connectedDevicServiceId = null;
			deviceInfoServiceId = null;
			notifyCharacteristicsId = null;
			writeCharacteristicsId = null;
			wx.getBLEDeviceServices({
				deviceId: connectedDeviceId,
				success: function (res) {
					var devServices = res.services;

					for (var i = 0; i < devServices.length; i++) {
						var devUUID = res.services[i].uuid;

						if (connectedDevicServiceId == null && devUUID.indexOf("F000FFC0") != 0 && devUUID.indexOf("000018F0") != 0 && devUUID.indexOf("00001800") != 0 && devUUID.indexOf("0000180A") != 0 && devUUID.indexOf("00001801") != 0) {
							connectedDevicServiceId = devUUID;
						}

						if (devUUID.indexOf("0000180A") == 0) {
							deviceInfoServiceId = devUUID;
						}
					}

					console.log("Sertvice  " + connectedDevicServiceId);
					wx.getBLEDeviceCharacteristics({
						deviceId: connectedDeviceId,
						serviceId: connectedDevicServiceId,
						success: function (res) {
							for (var i = 0; i < res.characteristics.length; i++) {
								if (res.characteristics[i].properties.notify) {
									if (notifyCharacteristicsId == null && res.characteristics[i].uuid.indexOf("0000FF03") != 0) {
										notifyCharacteristicsId = res.characteristics[i].uuid;
									}
								}

								if (writeCharacteristicsId == null && res.characteristics[i].properties.write) {
									writeCharacteristicsId = res.characteristics[i].uuid;
								}
							}

							console.log("notify    " + notifyCharacteristicsId);
							console.log("write     " + writeCharacteristicsId);
							wx.notifyBLECharacteristicValueChange({
								"deviceId": connectedDeviceId,
								"serviceId": connectedDevicServiceId,
								"characteristicId": notifyCharacteristicsId,
								"state": true,
								"success": function (res) {}
							});
							console.log("info      " + deviceInfoServiceId);
							wx.getBLEDeviceCharacteristics({
								"deviceId": connectedDeviceId,
								"serviceId": deviceInfoServiceId,
								"success": function (res) {
									for (var i = 0; i < res.characteristics.length; i++) {
										if (res.characteristics[i].uuid.indexOf("00002A24") == 0) {
											wx.readBLECharacteristicValue({
												"characteristicId": res.characteristics[i].uuid,
												"deviceId": connectedDeviceId,
												"serviceId": deviceInfoServiceId
											});
											break;
										}
									}
								},
								"fail": function () {
									console.log("获取蓝牙模块信息失败");

									if (setCurrentPrinterInfo) {
										setCurrentPrinterInfo();
									}
								},
								"complete": function () {}
							});
						},
						"fail": function () {
							console.log("获取特征值失败");

							if (setCurrentPrinterInfo) {
								setCurrentPrinterInfo();
							}
						},
						"complete": function () {}
					});
				}
			});
		},
		"fail": function (err) {
			console.log("连接蓝牙设备失败", err.errCode, err.errMsg);

			if (setCurrentPrinterInfo) {
				setCurrentPrinterInfo();
			}
		},
		"complete": function () {}
	});
}

function parseDeviceInfo(devData) {
	var receiveData = bin2String(devData.value);

	maxSendDataLength = 180;
	sendDataWaitTime = 33;

	var recDataArr = receiveData.split("-");

	if (recDataArr.length > 0) {
		var recDataItem = recDataArr.pop();

		recDataItem = recDataItem.toUpperCase();

		if (recDataItem == "MT_DF1") {
			maxSendDataLength = 120;
			sendDataWaitTime = 20;
		} else if (recDataItem.indexOf("DF") == 0) {
			recDataItem = recDataItem.replace("DF", "");

			var recDataVal = parseInt(recDataItem, 16);

			if (recDataVal & 1) {
				maxSendDataLength = 180;
				sendDataWaitTime = 18;
			} else if (recDataVal & 2) {
				maxSendDataLength = 120;
				sendDataWaitTime = 20;
			} else if (recDataVal & 4) {
				maxSendDataLength = 240;
				sendDataWaitTime = 1;
			}
		}
	}

	console.log("蓝牙发送长度" + maxSendDataLength);
	checkDPI();
}

function parseDPI(dpi) {
	var _0x266533 = 0;
	var _0x4d2c0c = dpi[2];

	if (_0x4d2c0c == 1) {
		_0x266533 = dpi[3];
	} else {
		var _0x28ca4a = dpi[3];
		var _0x28b53c = dpi[4];
		_0x266533 = (_0x28ca4a << 8) + _0x28b53c;
	}

	currentPrinter.DPI = _0x266533;
	checkPrintWidth();
}

function parsePrintWidth(_0x298306) {
	var _0xeb37c1 = _0x298306[3];
	var _0x26a9cd = _0x298306[4];

	var _0x55c8a0 = (_0xeb37c1 << 8) + _0x26a9cd;

	currentPrinter.width = _0x55c8a0;
	wx.getSystemInfo({
		success: function (res) {
			if (res.platform == "ios") {
				checkDeviceType(true);

				if (sDidConnectedHandler) {
					sDidConnectedHandler();
				}
			} else if (res.platform == "android") {
				checkDeviceType(false);

				if (sDidConnectedHandler) {
					sDidConnectedHandler();
				}

				wx.setBLEMTU({
					"deviceId": connectedDeviceId,
					"mtu": 512
				});
			}
		}
	});
}

function parseBufferSize(buf) {
	var _0x5d9383 = 0;
	var _0x12edd7 = buf[3];

	if (_0x12edd7 >= 192) {
		var _0xbc8196 = buf[3];
		var _0x1091f7 = buf[4];
		_0x5d9383 = (_0xbc8196 << 8) + _0x1091f7;
	} else {
		_0x5d9383 = _0x12edd7;
	}

	postDatasWithBuffer(_0x5d9383 * 500);
}

function disconnectPeripheral() {
	wx.closeBLEConnection({
		"deviceId": connectedDeviceId,
		"success": function (res) {
            if(getApp().globalData._that) {
                getApp().globalData._that.setData({
                    printDisabled: true
                })
            }            
        }
	});
}

/**
 * 
 * @param {*} handleDevList 
 */
function scanedPeripherals(handleDevList) {
	wx.getBluetoothDevices({
		success(res) {
			console.log("【ble3】getBluetoothDevices--->", res)

			var devList = new Array();

			for (var i = 0; i < res.devices.length; i++) {
				let devName = res.devices[i].name;

				if (isMyPrinterForName(devName)) {
					console.log("---printerName>", devName)
					devList.push(res.devices[i]);
				}
			}

			if (handleDevList) {
				handleDevList(devList);
			}
		}
	});
}

function sendData(imageArr, didSendDataHandler) {
	if (printList == null) {
		printList = new Array();
	}

	if (imageArr != null) {
		printList.push(imageArr);

		if (printList.length > 0) {
			var printer = printList[0];

			if (printer.length > 0) {
				sDidSendDataHandler = didSendDataHandler;
				checkBufferSize();
			} else {
				clearInterval(interval);
				printList.splice(0, 1);

				if (didSendDataHandler) {
					didSendDataHandler();
				}
			}
		}
	}
}

function postDatasWithBuffer(bufLen) {
	if (bufLen < 2000) {
		// TOLOOK
		setTimeout(() => {
			checkBufferSize();
		}, 50);
	} else {
		printHex = "";
		var _0x439b55 = printList[0];

		if (_0x439b55 != null) {
			for (; _0x439b55.length > 0; _0x439b55.splice(0, 1)) {
				var _0x52e3ce = _0x439b55[0];

				if (printHex.length + _0x52e3ce.length >= bufLen) {
					break;
				}

				printHex += _0x52e3ce;
			}
		}

		postHexValue(function () {
			if (_0x439b55 != null && _0x439b55.length > 0) {
				checkBufferSize();
			} else {
				printList.splice(0, 1);

				if (sDidSendDataHandler) {
					sDidSendDataHandler();
				}
			}
		});
	}
}

function postHexValue(hexVal) {
	sDidSendHexHandler = hexVal;
	postHex();
}

function postHex() {
	if (printHex != null && printHex.length > 0) {
		interval = // TOLOOK
			setTimeout(function () {
				var printVal;

				if (printHex != null && printHex.length > maxSendDataLength) {
					printVal = printHex.substr(0, maxSendDataLength);
					printHex = printHex.substring(maxSendDataLength);
				} else {
					printVal = printHex;
					printHex = "";
				}

				if (printVal && printVal.length > 0) {
					var sendDataBuf = new Uint8Array(printVal.match(/[\da-f]{2}/gi).map(function (_0x30de81) {
						return parseInt(_0x30de81, 16);
					}));

					wx.writeBLECharacteristicValue({
						"deviceId": connectedDeviceId,
						"serviceId": connectedDevicServiceId,
						"characteristicId": writeCharacteristicsId,
						"value": sendDataBuf.buffer,
						"success": function (_0x4926f5) {}
					});
				}

				postHex();
			}, sendDataWaitTime);
	} else {
		if (sDidSendHexHandler) {
			sDidSendHexHandler();
		}
	}
}

function checkDeviceType(isIos) {
	if (isIos) {
		sendCMD("1F78010388");
	} else {
		sendCMD("1F78010288");
	}
}

function checkDPI() {
	sendCMD("1F710088");
}

function checkPrintWidth() {
	sendCMD("1F720088");
}

function checkBufferSize() {
	sendCMD("1F770088");
}

function sendCMD(cmd) {
	var sendCmdBuf = new Uint8Array(cmd.match(/[\da-f]{2}/gi).map(function (val) {
		return parseInt(val, 16);
	}));

	wx.writeBLECharacteristicValue({
		"deviceId": connectedDeviceId,
		"serviceId": connectedDevicServiceId,
		"characteristicId": writeCharacteristicsId,
		"value": sendCmdBuf.buffer,
		"success": function (res) {}
	});
}

function bin2String(binVal) {
	var resultBuf = new Uint8Array(binVal);

	var resultStr = "";

	for (var i = 0; i < resultBuf.length; i++) {
		resultStr += String.fromCharCode(resultBuf[i]);
	}

	return resultStr;
}



function isMyPrinterForName(devName) {
	if (devName == null || devName.length == 0) {
		return false;
	}

	var nameArr = devName.toUpperCase().split("-");
	let bleName = ''
	if (nameArr.length > 1) {
		bleName = nameArr[nameArr.length - 1]
		if (bleName.length < 8) {
			return false;
		}
	} else {
		return false;
	}

	var namePatter = new RegExp("^[A-Z]{0,2}[0-9]{4,5}[0-9A-Z]{2,3}[0-9]{2}$", "g");

	if (!namePatter.exec(bleName)) {
		return false;
	}

	var nameNumPattern = new RegExp("^[0-9]+", "g");

	var nameIsNumStart = nameNumPattern.exec(bleName);

	var _0x42533d = "";
	var _0x5bd705 = 0;

	if (bleName.charAt(1) < "0" || bleName.charAt(1) > "9") {
		_0x42533d = bleName.substring(0, 2);
		bleName = bleName.substring(2, bleName.length);
		_0x5bd705 += _0x42533d.charCodeAt(0) * 11;
		_0x5bd705 += _0x42533d.charCodeAt(1) * 12;
	} else if (bleName.charAt(0) < "0" || bleName.charAt(0) > "9") {
		_0x42533d = bleName.substring(0, 1);
		bleName = bleName.substring(1, bleName.length);
		_0x5bd705 += _0x42533d.charCodeAt(0) * 17;
	}

	console.log("--->isPrinterName:_0x42533d=", _0x42533d, ",_0x5bd705=", _0x5bd705, ",bleName=", bleName)

	if (_0x42533d.toUpperCase() == "D" || _0x42533d.toUpperCase() == "O") {} else if (bleName.length < 8) {
		return false;
	} else {
		if (supportPrefixKeys.length > 0) {
			for (var i = 0; i < supportPrefixKeys.length; i++) {
				var _0x124562 = supportPrefixKeys[i];

				if (_0x124562.length > 0) {
					var _0x34bc3c = bleName.substring(0, _0x124562.length);

					if (_0x34bc3c.toUpperCase() == _0x124562.toUpperCase()) {
						break;
					}
				} else {
					return false;
				}
			}
		}
	}

	if (!nameIsNumStart || bleName.length >= 9 || bleName.charAt(3) != "0") {
		if (nameIsNumStart) {
			_0x5bd705 += (bleName.charAt(0) - "0") * 2;
			_0x5bd705 += (bleName.charAt(1) - "0") * 3;
			_0x5bd705 += (bleName.charAt(2) - "0") * 5;

			for (var i = 4; i < bleName.length; ++i) {
				_0x5bd705 += (bleName.charAt(i) - "0") * ((i & 1) == 0 ? 7 : 9);
			}
		} else {
			_0x5bd705 += bleName.charAt(0) * 2;
			_0x5bd705 += bleName.charAt(1) * 3;
			_0x5bd705 += bleName.charAt(2) * 5;

			for (var i = 4; i < bleName.length; ++i) {
				_0x5bd705 += bleName.charCodeAt(i) * ((i & 1) == 0 ? 7 : 9);
			}
		}

		var _0x33eeff = _0x5bd705 % 10;

		if ("5682904137".charAt(_0x33eeff) != bleName.charAt(3)) {
			return false;
		}
	}

	return true;
}


function ab2hex(buffer) {
	var hexArr = Array.prototype.map.call(
		new Uint8Array(buffer),
		function (bit) {
			return ('00' + bit.toString(16)).slice(-2)
		}
	)
	return hexArr.join('');
}